/**
 * 拦截器管理器
 * 提供统一的请求/响应拦截器配置
 */

import { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';
import { message } from 'antd';

/**
 * 拦截器配置接口
 */
export interface InterceptorConfig {
  /** 是否启用请求日志 */
  enableRequestLog?: boolean;
  /** 是否启用响应日志 */
  enableResponseLog?: boolean;
  /** 是否启用认证拦截 */
  enableAuthInterceptor?: boolean;
  /** 是否启用错误处理 */
  enableErrorHandler?: boolean;
  /** 是否启用重试机制 */
  enableRetry?: boolean;
  /** 重试次数 */
  retryCount?: number;
  /** 重试延迟（毫秒） */
  retryDelay?: number;
  /** 是否启用加载状态 */
  enableLoading?: boolean;
}

/**
 * 请求拦截器类
 */
export class RequestInterceptor {
  private static instance: RequestInterceptor;
  private loadingCount = 0;
  private loadingHandlers: Set<(loading: boolean) => void> = new Set();

  private constructor() {}

  /**
   * 获取单例实例
   */
  public static getInstance(): RequestInterceptor {
    if (!RequestInterceptor.instance) {
      RequestInterceptor.instance = new RequestInterceptor();
    }
    return RequestInterceptor.instance;
  }

  /**
   * 添加加载状态处理器
   */
  public addLoadingHandler(handler: (loading: boolean) => void): void {
    this.loadingHandlers.add(handler);
  }

  /**
   * 移除加载状态处理器
   */
  public removeLoadingHandler(handler: (loading: boolean) => void): void {
    this.loadingHandlers.delete(handler);
  }

  /**
   * 设置加载状态
   */
  private setLoading(loading: boolean): void {
    this.loadingHandlers.forEach(handler => handler(loading));
  }

  /**
   * 认证拦截器
   */
  public authInterceptor(config: AxiosRequestConfig): AxiosRequestConfig {
    // 从本地存储获取token
    const token = localStorage.getItem('access_token');
    
    if (token && config.headers) {
      config.headers.Authorization = `Bearer ${token}`;
    }

    // 添加请求时间戳
    if (config.headers) {
      config.headers['X-Request-Timestamp'] = Date.now().toString();
    }

    return config;
  }

  /**
   * 日志拦截器
   */
  public logInterceptor(config: AxiosRequestConfig): AxiosRequestConfig {
    if (process.env.NODE_ENV === 'development') {
      console.log('🚀 [Request]', {
        method: config.method?.toUpperCase(),
        url: config.url,
        params: config.params,
        data: config.data,
        timestamp: new Date().toISOString(),
      });
    }

    return config;
  }

  /**
   * 加载状态拦截器
   */
  public loadingInterceptor(config: AxiosRequestConfig): AxiosRequestConfig {
    this.loadingCount++;
    if (this.loadingCount === 1) {
      this.setLoading(true);
    }

    return config;
  }

  /**
   * 请求错误拦截器
   */
  public requestErrorInterceptor(error: any): Promise<never> {
    console.error('❌ [Request Error]', error);
    
    // 减少加载计数
    this.loadingCount--;
    if (this.loadingCount === 0) {
      this.setLoading(false);
    }

    return Promise.reject(error);
  }

  /**
   * 应用请求拦截器
   */
  public applyRequestInterceptors(
    axiosInstance: AxiosInstance,
    config: InterceptorConfig = {}
  ): void {
    const {
      enableAuthInterceptor = true,
      enableRequestLog = true,
      enableLoading = true,
    } = config;

    // 认证拦截器
    if (enableAuthInterceptor) {
      axiosInstance.interceptors.request.use(
        (config) => this.authInterceptor(config),
        (error) => this.requestErrorInterceptor(error)
      );
    }

    // 日志拦截器
    if (enableRequestLog) {
      axiosInstance.interceptors.request.use(
        (config) => this.logInterceptor(config),
        (error) => this.requestErrorInterceptor(error)
      );
    }

    // 加载状态拦截器
    if (enableLoading) {
      axiosInstance.interceptors.request.use(
        (config) => this.loadingInterceptor(config),
        (error) => this.requestErrorInterceptor(error)
      );
    }
  }
}

/**
 * 响应拦截器类
 */
export class ResponseInterceptor {
  private static instance: ResponseInterceptor;

  private constructor() {}

  /**
   * 获取单例实例
   */
  public static getInstance(): ResponseInterceptor {
    if (!ResponseInterceptor.instance) {
      ResponseInterceptor.instance = new ResponseInterceptor();
    }
    return ResponseInterceptor.instance;
  }

  /**
   * 响应日志拦截器
   */
  public logInterceptor(response: AxiosResponse): AxiosResponse {
    if (process.env.NODE_ENV === 'development') {
      console.log('✅ [Response]', {
        url: response.config.url,
        status: response.status,
        data: response.data,
        timestamp: new Date().toISOString(),
      });
    }

    return response;
  }

  /**
   * 业务响应拦截器
   */
  public businessInterceptor(response: AxiosResponse): AxiosResponse {
    const { data } = response;

    // 统一响应格式处理
    if (data && typeof data === 'object') {
      // 如果后端返回统一格式
      if ('code' in data && 'success' in data) {
        if (!data.success) {
          // 业务错误，抛出异常
          const error = new Error(data.message || '业务错误');
          (error as any).code = data.code;
          (error as any).response = response;
          throw error;
        }
      }
    }

    return response;
  }

  /**
   * 加载状态拦截器
   */
  public loadingInterceptor(response: AxiosResponse): AxiosResponse {
    const requestInterceptor = RequestInterceptor.getInstance();
    
    // 减少加载计数
    (requestInterceptor as any).loadingCount--;
    if ((requestInterceptor as any).loadingCount === 0) {
      (requestInterceptor as any).setLoading(false);
    }

    return response;
  }

  /**
   * HTTP错误拦截器
   */
  public httpErrorInterceptor(error: AxiosError): Promise<never> {
    const { response, config } = error;

    if (response) {
      // 服务器返回错误状态码
      const { status, data } = response;

      switch (status) {
        case 400:
          message.error(data?.message || '请求参数错误');
          break;
        case 401:
          message.error('登录已过期，请重新登录');
          localStorage.removeItem('access_token');
          // 延迟跳转，避免消息被覆盖
          setTimeout(() => {
            window.location.href = '/login';
          }, 2000);
          break;
        case 403:
          message.error('权限不足，无法执行此操作');
          break;
        case 404:
          message.error('请求的资源不存在');
          break;
        case 408:
          message.error('请求超时，请检查网络连接');
          break;
        case 500:
          message.error('服务器内部错误，请稍后重试');
          break;
        case 502:
        case 503:
        case 504:
          message.error('服务暂时不可用，请稍后重试');
          break;
        default:
          message.error(`请求失败: ${status}`);
      }

      // 记录错误日志
      console.error('❌ [HTTP Error]', {
        url: config?.url,
        method: config?.method,
        status: response.status,
        message: data?.message || error.message,
        timestamp: new Date().toISOString(),
      });
    } else if (error.request) {
      // 请求已发出但没有收到响应
      message.error('网络连接错误，请检查网络设置');
      
      console.error('❌ [Network Error]', {
        url: config?.url,
        method: config?.method,
        message: error.message,
        timestamp: new Date().toISOString(),
      });
    } else {
      // 请求配置错误
      message.error('请求配置错误');
      
      console.error('❌ [Config Error]', {
        message: error.message,
        timestamp: new Date().toISOString(),
      });
    }

    // 处理加载状态
    const requestInterceptor = RequestInterceptor.getInstance();
    (requestInterceptor as any).loadingCount--;
    if ((requestInterceptor as any).loadingCount === 0) {
      (requestInterceptor as any).setLoading(false);
    }

    return Promise.reject(error);
  }

  /**
   * 重试拦截器
   */
  public createRetryInterceptor(retryCount: number = 3, retryDelay: number = 1000) {
    return async (error: AxiosError): Promise<AxiosResponse> => {
      const { config, response } = error;

      // 如果没有重试配置或已达到最大重试次数
      if (!config || !retryCount || (config as any).__retryCount >= retryCount) {
        return Promise.reject(error);
      }

      // 只对网络错误和5xx错误进行重试
      if (!response || (response.status >= 500 && response.status < 600)) {
        // 增加重试计数
        (config as any).__retryCount = ((config as any).__retryCount || 0) + 1;

        // 延迟重试
        await new Promise(resolve => setTimeout(resolve, retryDelay * ((config as any).__retryCount || 1)));

        console.warn(`🔄 [Retry] 第 ${(config as any).__retryCount} 次重试:`, config?.url);

        // 重新发起请求
        return (error.config as any).axiosInstance(config);
      }

      return Promise.reject(error);
    };
  }

  /**
   * 应用响应拦截器
   */
  public applyResponseInterceptors(
    axiosInstance: AxiosInstance,
    config: InterceptorConfig = {}
  ): void {
    const {
      enableResponseLog = true,
      enableErrorHandler = true,
      enableRetry = false,
      retryCount = 3,
      retryDelay = 1000,
    } = config;

    // 日志拦截器
    if (enableResponseLog) {
      axiosInstance.interceptors.response.use(
        (response) => this.logInterceptor(response),
        (error) => this.httpErrorInterceptor(error)
      );
    }

    // 业务响应拦截器
    axiosInstance.interceptors.response.use(
      (response) => this.businessInterceptor(response),
      (error) => this.httpErrorInterceptor(error)
    );

    // 加载状态拦截器
    axiosInstance.interceptors.response.use(
      (response) => this.loadingInterceptor(response),
      (error) => {
        this.httpErrorInterceptor(error);
        return Promise.reject(error);
      }
    );

    // 重试拦截器
    if (enableRetry) {
      axiosInstance.interceptors.response.use(
        undefined,
        this.createRetryInterceptor(retryCount, retryDelay)
      );
    }
  }
}

/**
 * 拦截器管理器
 */
export class InterceptorManager {
  private static instance: InterceptorManager;
  private requestInterceptor: RequestInterceptor;
  private responseInterceptor: ResponseInterceptor;

  private constructor() {
    this.requestInterceptor = RequestInterceptor.getInstance();
    this.responseInterceptor = ResponseInterceptor.getInstance();
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): InterceptorManager {
    if (!InterceptorManager.instance) {
      InterceptorManager.instance = new InterceptorManager();
    }
    return InterceptorManager.instance;
  }

  /**
   * 为Axios实例应用所有拦截器
   */
  public applyInterceptors(
    axiosInstance: AxiosInstance,
    config: InterceptorConfig = {}
  ): void {
    // 存储axios实例引用，用于重试
    (axiosInstance as any).defaults.axiosInstance = axiosInstance;

    // 应用请求拦截器
    this.requestInterceptor.applyRequestInterceptors(axiosInstance, config);

    // 应用响应拦截器
    this.responseInterceptor.applyResponseInterceptors(axiosInstance, config);
  }

  /**
   * 添加加载状态处理器
   */
  public addLoadingHandler(handler: (loading: boolean) => void): void {
    this.requestInterceptor.addLoadingHandler(handler);
  }

  /**
   * 移除加载状态处理器
   */
  public removeLoadingHandler(handler: (loading: boolean) => void): void {
    this.requestInterceptor.removeLoadingHandler(handler);
  }

  /**
   * 获取当前加载状态
   */
  public getLoadingCount(): number {
    return (this.requestInterceptor as any).loadingCount;
  }

  /**
   * 清除所有拦截器
   */
  public clearInterceptors(axiosInstance: AxiosInstance): void {
    axiosInstance.interceptors.request.clear();
    axiosInstance.interceptors.response.clear();
  }

  /**
   * 重置加载状态
   */
  public resetLoadingState(): void {
    (this.requestInterceptor as any).loadingCount = 0;
    (this.requestInterceptor as any).setLoading(false);
  }
}

// 导出单例实例
export const interceptorManager = InterceptorManager.getInstance();

export default InterceptorManager;